/*
 * LogisticRegTrainer.h
 *
 *  Created on: Dec 23, 2009
 *      Author: tunpixel
 */

#ifndef LOGISTICREGTRAINER_H__
#define LOGISTICREGTRAINER_H__


namespace bouguerra {

#include "../common/Common.h"

class LogisticRegTrainer {

	public:
		CvMat* thetas;
		float getTheta(int pixelIndex, int featureIndex , IplImage* image, IplImage* label);
		int model;
		void manipulate(IplImage *image);
		LogisticRegTrainer();
		LogisticRegHelper helper;
		virtual ~LogisticRegTrainer(){};

	};

	LogisticRegTrainer::LogisticRegTrainer() {
		thetas = cvCreateMat(1, 4, CV_32FC1);
		model = COLOR_DIFFERENCES_MODEL;
	}

	void LogisticRegTrainer::manipulate(IplImage *image)
	{

		if(model == COLOR_DIFFERENCES_MODEL)
			return;

		IplImage *avg = cvCloneImage(image);
		IplImage* result = cvCloneImage(image);
		IplImage* blurredImage = cvCloneImage(image);
		IplImage* absDiff = cvCloneImage(image);

		cvSmooth(image, image);

		//cvSet(avg,cvAvg(image)  );
		cvSmooth(image, blurredImage, CV_MEDIAN,15, 15);

		cvAbsDiff(image, blurredImage, absDiff);
		cvCopy(absDiff, image);

/*
		cvSmooth(image, blurredImage);
		cvSet(avg,cvAvg(blurredImage)  );

		cvAbsDiff(blurredImage, avg, result);
		cvCopy(result, image);
*/

		cvReleaseImage(&avg);
		cvReleaseImage(&result);
		cvReleaseImage(&absDiff);
		cvReleaseImage(&blurredImage);
	}

	float LogisticRegTrainer::getTheta(int pixelIndex, int featureIndex , IplImage* image, IplImage* label) {

			uchar* y_ptr = (uchar*) (label->imageData + pixelIndex);
			float y = y_ptr[0] > 100 ? 0 : 1;
			float b, g, r;

			uchar* imagePointer = (uchar*) (image->imageData + pixelIndex);

			b = imagePointer[0] ;//(int)* (uchar*)(image->imageData + imageIndex ) ;
			g = imagePointer[1] ;//(int)* (uchar*)(image->imageData + imageIndex) +4;
			r = imagePointer[2] ;//(int)* (uchar*)(image->imageData + imageIndex) +8;

			float feature;
			if (featureIndex == 0)
				feature = 1;
			else if (featureIndex == 1)
				feature = b;
			else if (featureIndex == 2)
				feature = g;
			else
				feature = r;

			float theta_0 = *(float*) (thetas->data.ptr);
			float theta_1 = *(float*) (thetas->data.ptr + 4);
			float theta_2 = *(float*) (thetas->data.ptr + 8);
			float theta_3 = *(float*) (thetas->data.ptr + 12);

			float sigma = theta_0 + theta_1 * b + theta_2 * g + theta_3 * r;
			double e = exp(-1.0 * sigma);
			float hypothesis = 1.0 / (1.0 + e);

			return ALPHA * (y - hypothesis) * feature;
	}
}

#endif /* LOGISTICREGTRAINER_H__ */
